package com.wyt.common.file.image;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.net.ssl.*;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Objects;

public class ImageDownloadUtil {
    private static Logger logger = LoggerFactory.getLogger(ImageDownloadUtil.class);

    /** 核心方法，用于https类型网络图片流的获取，避免因https的验证导致下载失败 */
    final static HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    };
    private static void trustAllHosts() {
        final String TAG = "trustAllHosts";
        // Create a trust manager that does not validate certificate chains
        TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
            public X509Certificate[] getAcceptedIssuers() {
                return new X509Certificate[] {};
            }
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                logger.info(TAG, "checkClientTrusted");
            }
            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                logger.info(TAG, "checkServerTrusted");
            }
        } };
        // Install the all-trusting trust manager
        try {
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, trustAllCerts, new java.security.SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 浏览器下载网络图片到本地
     */
    public void downloadPicTool(String filename, String picUrl, HttpServletResponse response) {
        InputStream in = null;
        OutputStream out = null;
        try {
            //读取文件流
            URL imageUrl = new URL(picUrl);
            HttpURLConnection httpURLConnection = null;
            trustAllHosts();
            if (imageUrl.getProtocol().toLowerCase().equals("https")) {
                HttpsURLConnection con = (HttpsURLConnection) imageUrl.openConnection();
                con.setHostnameVerifier(DO_NOT_VERIFY);
                httpURLConnection = con;
            } else {
                httpURLConnection = (HttpURLConnection) imageUrl.openConnection();
            }
            httpURLConnection.setRequestProperty("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0.1) Gecko/20100101 Firefox/4.0.1");
            httpURLConnection.setConnectTimeout(5 * 1000);
            int filesize = httpURLConnection.getContentLength(); // 取数据长度
            in = httpURLConnection.getInputStream();
            out = response.getOutputStream();
            //启动下载
            response.setHeader("content-disposition", "attachment;filename=\"" + filename + "\"");
            response.addHeader("Content-Length", "" + filesize);
            response.setHeader("content-type", "application/x-download");
            int len = 1;
            byte[] b = new byte[1024];
            while ((len = in.read(b)) != -1) {
                out.write(b, 0, len);
            }
        } catch (Exception e) {
            logger.error("图片下载进入异常fileName = [{}], picUrl = [{}]：",filename,picUrl,e);
        } finally {
            try {
                out.close();
                in.close();
            } catch (IOException e) {
                logger.error("流关闭异常：",e);
            }
        }
    }

    /**
     * 后台下载网络图片到本地
     */
    private void downPicToLocal(String picUrl,String path) {
        try {
            URL imageUrl = new URL(picUrl);
            HttpURLConnection httpURLConnection = null;
            trustAllHosts();
            if (imageUrl.getProtocol().toLowerCase().equals("https")) {
                HttpsURLConnection con = (HttpsURLConnection) imageUrl.openConnection();
                con.setHostnameVerifier(DO_NOT_VERIFY);
                httpURLConnection = con;
            } else {
                httpURLConnection = (HttpURLConnection) imageUrl.openConnection();
            }
            httpURLConnection.setRequestProperty("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0.1) Gecko/20100101 Firefox/4.0.1");
            httpURLConnection.setConnectTimeout(5 * 1000);
            InputStream in = httpURLConnection.getInputStream();
            FileOutputStream fileOutputStream = new FileOutputStream(new File(path));
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int length;
            while ((length = in.read(buffer)) > 0) {
                output.write(buffer, 0, length);
            }
            fileOutputStream.write(output.toByteArray());
            in.close();
            fileOutputStream.close();
        } catch (Exception e) {
            logger.error("下载图片到本地出错，图片url = [{}],下载路径名称为 = [{}]",picUrl,path);
        }
    }

    /**
     * 网络图片转BASE64
     */
    public static String httpsImage2Base64(String httpUrl) {
        BufferedReader input = null;
        StringBuilder sb = null;
        URL url = null;
        HttpURLConnection con = null;
        final ByteArrayOutputStream data = new ByteArrayOutputStream();
        InputStream is = null;
        try {
            url = new URL(httpUrl);
            try {
                // trust all hosts
                trustAllHosts();
                HttpsURLConnection https = (HttpsURLConnection)url.openConnection();
                if (url.getProtocol().toLowerCase().equals("https")) {
                    https.setHostnameVerifier(DO_NOT_VERIFY);
                    con = https;
                } else {
                    con = (HttpURLConnection)url.openConnection();
                }
                final byte[] by = new byte[1024];
                is = con.getInputStream();
                // 将内容读取内存中
                int len = -1;
                while ((len = is.read(by)) != -1) {
                    data.write(by, 0, len);
                }
                // 对字节数组Base64编码
                BASE64Encoder encoder = new BASE64Encoder();
                return encoder.encode(data.toByteArray());
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (MalformedURLException e1) {
            e1.printStackTrace();
        } finally {
            // close buffered
            if (input != null) {
                try {
                    input.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }}

            // disconnecting releases the resources held by a connection so they may be closed or reused
            if (con != null) {
                con.disconnect();
            }
        }
        return null;
    }

    /**
     * 本地图片转换Base64的方法
     */
    public static String localImage2Base64(String imgPath) {
        InputStream in = null;
        // 读取图片字节数组
        try {
            in = new FileInputStream(imgPath);
            byte[] data = new byte[in.available()];
            in.read(data);
            // 对字节数组Base64编码
            BASE64Encoder encoder = new BASE64Encoder();
            // 返回Base64编码过的字节数组字符串
            return encoder.encode(Objects.requireNonNull(data));
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    /**
     * base64编码转存成本地图片
     */
    public static String base642LocalImage(String base64Images){
//        String filePath = System.getProperty("user.dir").replace("\\", "/") + "/config/";
        String filePath = System.getProperty("user.dir").replace("\\", "/") + "/";
        String picName = System.currentTimeMillis() + ".jpg";
        try {
            //Base64解码
            byte[] b = new BASE64Decoder().decodeBuffer(base64Images);
            for(int i=0;i<b.length;++i)
            {
                if(b[i]<0)
                {
                    //调整异常数据
                    b[i]+=256;
                }
            }
            //新生成的图片
            OutputStream out = new FileOutputStream(filePath+picName);
            out.write(b);
            out.flush();
            out.close();
            return filePath+picName;
        }catch (Exception e){
            logger.warn("base64编码转存成本地图片失败，报错信息为："+e.toString());
        }
        return null;
    }

    public static void main(String[] args) {
        String base64 = localImage2Base64("D:\\data\\1605016521.jpg");
        System.out.println(base64.length());
    }


}
